package com.hanock.sm.fork2d;


import android.graphics.Rect;
import android.graphics.RectF;


public class Button extends Node {
	
	private static final float SCALE_SPEED = 1.5f; // per sec
	private static final float COLOR_SPEED = 2f; // per sec
	private static final float SCALE_MIN = 1f;
	private static final float SCALE_MAX = 1.2f;
	private static final float COLOR_MIN = 0.7f;
	private static final float COLOR_MAX = 1f;

	private OnButtonListener listener;
	private int resId1;
	private int resId2;
	private Rect srcRect1;
	private Rect srcRect2;
	private float touchAreaScale;
	private boolean down;
	private boolean downScale;
	private boolean toggleWhenDown;
	private RectF rectF;
	
	
	public Button(int resId, OnButtonListener listener) {
		this(resId, null, resId, null, listener);
	}
	
	public Button(int resId1, int resId2, OnButtonListener listener) {
		this(resId1, null, resId2, null, listener);
	}
	
	public Button(int resId1, Rect srcRect1, int resId2, Rect srcRect2, OnButtonListener listener) {
		
		this.resId1 = resId1;
		this.resId2 = resId2;
		this.srcRect1 = srcRect1;
		this.srcRect2 = srcRect2;
		this.listener = listener;
		
		this.down = false;
		this.rectF = new RectF();
		
		this.toggleWhenDown = false;
		
		touchAreaScale = 1;
		
		if (resId1 == resId2 || resId2 == 0){
			downScale = true;
		}
		else
			downScale = false;
	}
	
	@Override
	protected boolean onTouch(float x, float y, TouchMode mode) {
		super.onTouch(x, y, mode);
		
		switch (mode){
		
		case DOWN:
			return onTouchDown(x, y);
			
		case UP:
			return onTouchUp(x, y);
			
		case MOVE:
			return onTouchMove(x, y);
			
		default:
			return false;
		}
	}
	
	public boolean onTouchMove(float x, float y) {
		
		if (isInTouchRect(x, y)){
			return true;
		}
		else{
			down = false;
			return false;
		}
	}
	
	public boolean onTouchDown(float x, float y) {
		
		if (down){
			down = false;
		}
		
		if (isInTouchRect(x, y)){
			
			if (toggleWhenDown)
				onToggle();
			else{
				down = true;
			}
			return true;
		}
		else{
			return false;
		}
	}
	
	public boolean onTouchUp(float x, float y) {
		
		if (!down || toggleWhenDown)
			return false;
		
		if (isInTouchRect(x, y)){
			down = false;
			onToggle();
			return true;
		}
		else{
			down = false;
			return false;
		}
	}
	
	private void onToggle(){
		if (listener != null)
			listener.onClick(this);
	}
	
	@Override
	public void draw(Canvas canvas) {
		if (down){
			if (downScale)
				draw1(canvas);
			else
				draw2(canvas);
		}
		else{
			draw1(canvas);
		}
	}
	
	private void draw1(Canvas canvas) {
		if (resId1 == 0)
			return;
		
		getDesRect(rectF);
		canvas.drawImage(srcRect1, rectF, resId1);
	}
	
	private void draw2(Canvas canvas) {
		if (resId2 == 0)
			return;
		
		getDesRect(rectF);
		canvas.drawImage(srcRect2, rectF, resId2);
	}
	
	@Override
	public void progress(int elapsed) {
		super.progress(elapsed);
		
		if (downScale){
			float s = getScaleX();
			float c = getRed();
			
			if (down){
				s += SCALE_SPEED*elapsed/1000f;
				c -= COLOR_SPEED*elapsed/1000f;
			}
			else{
				s -= SCALE_SPEED*elapsed/1000f;
				c += COLOR_SPEED*elapsed/1000f;
			}
			
			if (s < SCALE_MIN)
				s = SCALE_MIN;
			if (s > SCALE_MAX)
				s = SCALE_MAX;
			if (c < COLOR_MIN)
				c = COLOR_MIN;
			if (c > COLOR_MAX)
				c = COLOR_MAX;
			
			setScale(s, s);
			setColorf(c, c, c, 1);
		}
	}
	
	public boolean isInTouchRect(float x, float y){
		
		getDesRect(rectF);
		MathUtil.scaleRect(rectF, touchAreaScale, touchAreaScale);
		
		return MathUtil.contains(rectF, x, y);
	}
	
	
	// ----------------------------------------------------------------------
	// Getters & Setters Functions
	// ----------------------------------------------------------------------
	
	public void setResId1(int resId1) {
		this.resId1 = resId1;
	}
	
	public void setResId2(int resId2) {
		this.resId2 = resId2;
	}
	
	public void setResId(int resId1, int resId2) {
		this.resId1 = resId1;
		this.resId2 = resId2;
	}
	
	public void setResId(int resId) {
		this.resId1 = resId;
		this.resId2 = resId;
	}

	public void setToggleWhenDown(boolean toggleWhenDown) {
		this.toggleWhenDown = toggleWhenDown;
		
		if (toggleWhenDown)
			down = false;
	}
	
	public void setTouchAreaScale(float touchAreaScale) {
		this.touchAreaScale = touchAreaScale;
	}
	
	public boolean isToggleWhenDown() {
		return toggleWhenDown;
	}
	
	public boolean isDown() {
		return down;
	}
}














